home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / util / cli / mcomms_1_4.lha / Src / rxcontrol.c < prev    next >
C/C++ Source or Header  |  1995-08-24  |  11KB  |  370 lines

  1. /*
  2. **    rxcontrol.c - control ARexx features
  3. **    Copyright ⌐ 1994-95 Michael Letowski
  4. */
  5.  
  6. #define __USE_SYSBASE
  7.  
  8. #include <exec/types.h>
  9. #include <exec/execbase.h>
  10. #include <dos/rdargs.h>
  11. #include <rexx/rxslib.h>
  12. #include <intuition/intuition.h>
  13. #include <workbench/startup.h>
  14.  
  15. #include <support/types.h>
  16. #include <support/dos.h>
  17.  
  18. #include <proto/exec.h>
  19. #include <proto/dos.h>
  20. #include <proto/icon.h>
  21. #include <proto/intuition.h>
  22. #include <proto/rexxsyslib.h>
  23.  
  24. #include "rxcontrol.rev.h"
  25.  
  26. #define DOS_NAME                    "dos.library"
  27. #define DOS_VERN                    37L
  28. #define REXX_NAME                    "rexxsyslib.library"
  29. #define REXX_VERN                    36L
  30. #define INT_NAME                    "intuition.library"
  31. #define INT_VERN                    37L
  32. #define ICON_NAME                    "icon.library"
  33. #define ICON_VERN                    37L
  34.  
  35. #define RXPORT_NAME                "REXX"
  36.  
  37. #define TEMPLATE                    "RXC=CANCEL/S,HI=HALT/S,SUSPEND/S,RESUME/S,"\
  38.                                                     "TS=TRACESTART/S,TE=TRACEEND/S,"\
  39.                                                     "TCO=CONOPEN/S,TCC=CONCLOSE/S,"\
  40.                                                     "QUIET/S"
  41.  
  42. /* Options array indices (for WB arguments reading) */
  43. #define OPT_RXC                    0
  44. #define OPT_HI                    1
  45. #define OPT_SUSPEND            2
  46. #define OPT_RESUME            3
  47. #define OPT_TS                    4
  48. #define OPT_TE                    5
  49. #define OPT_TCO                    6
  50. #define OPT_TCC                    7
  51. #define OPT_QUIET                8
  52. #define OPT_COUNT                9
  53.  
  54. /* Messages */
  55. #define MSG_UNABLE_OPEN        "Unable to open '%s'\n"
  56. #define MSG_NOT_ACTIVE        "ARexx server not active\n"
  57. #define MSG_IS_SUSPENDED    "Execution is suspended\n"
  58. #define MSG_WILL_CLOSE        "RexxMaster will close\n"
  59. #define MSG_STATUS                "ARexx state:\n"\
  60.                                                     "%sTracing is %s\n"\
  61.                                                     "%sTrace console is %s\n%s%s%s%s"
  62. /* Other texts */
  63. #define MSG_OK                        "OK"
  64. #define MSG_ON                        "ON"
  65. #define MSG_OFF                        "OFF"
  66. #define MSG_OPEN                    "open"
  67. #define MSG_CLOSED                "closed"
  68. #define REQUEST_MSG                " Request"
  69. #define INFO_MSG                    " Information"
  70. #define SPC_TAB                        "  "
  71.  
  72. STATIC CONST TEXT VersionString[]=
  73.     VERSION(PROG_NAME,PROG_VERSION,PROG_REVISION,PROG_DATE);
  74.  
  75. struct Options
  76. {
  77.     LONG opt_RXC;
  78.     LONG opt_HI;
  79.     LONG opt_Suspend;
  80.     LONG opt_Resume;
  81.     LONG opt_TS;
  82.     LONG opt_TE;
  83.     LONG opt_TCO;
  84.     LONG opt_TCC;
  85.     LONG opt_Quiet;
  86. };    /* Options */
  87.  
  88. struct States
  89. {
  90.     STRPTR state_Tab1;    STRPTR state_Tracing;
  91.     STRPTR state_Tab2;    STRPTR state_Console;
  92.     STRPTR state_Tab3;    STRPTR state_Suspended;
  93.     STRPTR state_Tab4;    STRPTR state_WillClose;
  94. };    /* States */
  95.  
  96. struct Switch
  97. {
  98.     STRPTR sw_Name;
  99.     ULONG sw_Index;
  100. };    /* Switch */
  101.  
  102. STATIC LONG CLIMode(struct ExecBase *SysBase, struct DosLibrary *DOSBase);
  103. STATIC LONG WBMode(struct ExecBase *SysBase, struct DosLibrary *DOSBase);
  104. STATIC LONG DoOptions(struct MsgPort *port, struct Options *opts,
  105.                                             struct ExecBase *SysBase, struct DosLibrary *DOSBase,
  106.                                             struct RxsLib *RexxSysBase);
  107. STATIC VOID GetOptions(struct States *stat, STRPTR tab, struct RxsLib *rsb);
  108.  
  109. LONG RXControl(VOID)
  110. {
  111.     struct ExecBase *SysBase=*((struct ExecBase **)4);
  112.     struct DosLibrary *DOSBase;
  113.  
  114.     LONG RC=RETURN_FAIL;
  115.  
  116.     /* Open DOS */
  117.     unless(DOSBase=(struct DosLibrary *)OpenLibrary(DOS_NAME,DOS_VERN))
  118.         throw2(SetResult2(ERROR_INVALID_RESIDENT_LIBRARY),    NO_DOS);
  119.  
  120.     RC=FromWB ? WBMode(SysBase,DOSBase) : CLIMode(SysBase,DOSBase);
  121.  
  122.     /* Exceptions */
  123.     catch(NO_DOS,    CloseLibrary((struct Library *)DOSBase));
  124.     return(RC);
  125. }    /* RXControl */
  126.  
  127. /* CLI mode work */
  128. STATIC LONG CLIMode(struct ExecBase *SysBase, struct DosLibrary *DOSBase)
  129. {
  130.     struct RxsLib *RexxSysBase;
  131.  
  132.     struct Options Opts;
  133.     struct States Stat;
  134.     struct RDArgs *Args;
  135.     struct MsgPort *Port;
  136.     LONG RC=RETURN_FAIL;
  137.  
  138.     /* Open rexxsyslib.library */
  139.     unless(RexxSysBase=(struct RxsLib *)OpenLibrary(REXX_NAME,REXX_VERN))
  140.         throw2(CauseIoErr(ERROR_INVALID_RESIDENT_LIBRARY,NULL),    NO_REXX);
  141.  
  142.     /* Read arguments */
  143.     clear(&Opts);                                                                    /* Clear options buffer */
  144.     unless(Args=ReadArgs(TEMPLATE,(LONG *)&Opts,NULL))
  145.         throw2(PrintFault(IoErr(),NULL),    NO_ARGS);
  146.     /* Check args */
  147.     if(Opts.opt_Suspend && Opts.opt_Resume ||
  148.             Opts.opt_TS && Opts.opt_TE || Opts.opt_TCO && Opts.opt_TCC)
  149.         throw2(CauseIoErr(ERROR_TOO_MANY_ARGS,PROG_NAME),    BAD_ARGS);
  150.  
  151.     /* Check for REXX port */
  152.     Forbid();
  153.     unless(Port=FindPort(RXPORT_NAME))
  154.     {
  155.         Permit();
  156.         PutStr(MSG_NOT_ACTIVE);
  157.         throw(NOT_ACTIVE);
  158.     }
  159.     RC=DoOptions(Port,&Opts,SysBase,DOSBase,RexxSysBase);
  160.     Permit();
  161.  
  162.     GetOptions(&Stat,"\t",RexxSysBase);
  163.     unless(Opts.opt_Quiet)
  164.         VPrintf(MSG_STATUS,&Stat);
  165.  
  166.     /* Exceptions */
  167.     catch(NOT_ACTIVE,    );
  168.     catch(BAD_ARGS,        );
  169.     catch(NO_ARGS,        FreeArgs(Args));
  170.     catch(NO_REXX,        CloseLibrary((struct Library *)RexxSysBase));
  171.     return(RC);
  172. }    /* CLIMode */
  173.  
  174. /* Workbench mode stuff */
  175. STATIC LONG WBMode(struct ExecBase *SysBase, struct DosLibrary *DOSBase)
  176. {
  177.     struct IntuitionBase *IntuitionBase;
  178.     struct RxsLib *RexxSysBase;
  179.     struct Library *IconBase;
  180.  
  181.     STATIC CONST struct EasyStruct NoLibReq=            /* No library requster */
  182.     {
  183.         sizeof(struct EasyStruct),0,
  184.         PROJ_NAME REQUEST_MSG,
  185.         MSG_UNABLE_OPEN,
  186.         MSG_OK
  187.     };    /* NoLibReq */
  188.     STATIC CONST struct EasyStruct NotActiveReq=    /* No REXX requester definition */
  189.     {
  190.         sizeof(struct EasyStruct),0,
  191.         PROJ_NAME REQUEST_MSG,
  192.         MSG_NOT_ACTIVE,
  193.         MSG_OK
  194.     };    /* NotActiveReq */
  195.     STATIC CONST struct EasyStruct InfoReq=                /* Informations requester */
  196.     {
  197.         sizeof(struct EasyStruct),0,
  198.         PROJ_NAME INFO_MSG,
  199.         MSG_STATUS,
  200.         MSG_OK
  201.     };    /* InfoReq */
  202.     STATIC CONST struct Switch Switches[]=                /* ToolTypes switches */
  203.     {
  204.         {"CANCEL",            OPT_RXC},            {"RXC",    OPT_RXC},
  205.         {"HALT",                OPT_HI},            {"HI",    OPT_HI},
  206.         {"SUSPEND",            OPT_SUSPEND},
  207.         {"RESUME",            OPT_RESUME},
  208.         {"TRACESTART",    OPT_TS},            {"TS",    OPT_TS},
  209.         {"TRACEEND",        OPT_TE},            {"TE",    OPT_TE},
  210.         {"CONOPEN",            OPT_TCO},            {"TCO",    OPT_TCO},
  211.         {"CONCLOSE",        OPT_TCC},            {"TCC",    OPT_TCC},
  212.         {"QUIET",                OPT_QUIET}
  213.     };    /* Switches */
  214.  
  215.     struct Options Opts;
  216.     struct States Stat;
  217.     struct MsgPort *Port;
  218.     struct WBStartup *WBMsg;
  219.     struct WBArg *Args;
  220.     struct DiskObject *Object;
  221.     STRPTR *ToolArray;
  222.     BPTR OldDir;
  223.     ULONG I,J;
  224.     LONG RC=RETURN_FAIL;
  225.  
  226.     WaitPort(&ThisProcessS->pr_MsgPort);
  227.     WBMsg=(struct WBStartup *)GetMsg(&ThisProcessS->pr_MsgPort);
  228.  
  229.     /* Open libraries */
  230.     unless(IntuitionBase=(struct IntuitionBase *)OpenLibrary(INT_NAME,INT_VERN))
  231.         throw2(SetResult2(ERROR_INVALID_RESIDENT_LIBRARY),    NO_INT);
  232.     unless(IconBase=OpenLibrary(ICON_NAME,ICON_VERN))
  233.         throw2(EasyRequest(NULL,&NoLibReq,NULL,ICON_NAME),    NO_ICON);
  234.     unless(RexxSysBase=(struct RxsLib *)OpenLibrary(REXX_NAME,REXX_VERN))
  235.         throw2(EasyRequest(NULL,&NoLibReq,NULL,REXX_NAME),    NO_REXX);
  236.  
  237.     /* Read arguments */
  238.     clear(&Opts);                                                                    /* Clear options buffer */
  239.     for(I=0, Args=WBMsg->sm_ArgList; I<WBMsg->sm_NumArgs; I++, Args++)
  240.         if(Args->wa_Lock)                                                        /* Lock exists */
  241.         {
  242.             OldDir=CurrentDir(Args->wa_Lock);                    /* CD to icon directory */
  243.             if(Args->wa_Name && (Object=GetDiskObject(Args->wa_Name)))
  244.             {
  245.                 ToolArray=(STRPTR *)Object->do_ToolTypes;
  246.                 for(J=0; J<elems(Switches); J++)
  247.                     if(FindToolType(ToolArray,Switches[J].sw_Name))
  248.                         ((LONG *)&Opts)[Switches[J].sw_Index]=TRUE;
  249.                 FreeDiskObject(Object);
  250.             }
  251.             CurrentDir(OldDir);                                                /* CD back */
  252.         }
  253.     /* Check args */
  254.     if(Opts.opt_Suspend && Opts.opt_Resume ||
  255.             Opts.opt_TS && Opts.opt_TE || Opts.opt_TCO && Opts.opt_TCC)
  256.         throw2(SetIoErr(ERROR_TOO_MANY_ARGS),    BAD_ARGS);
  257.  
  258.     /* Check for REXX port */
  259.     Forbid();                                                                            /* Make sure a port doesn't disappear */
  260.     unless(Port=FindPort(RXPORT_NAME))
  261.     {
  262.         Permit();
  263.         EasyRequestArgs(NULL,&NotActiveReq,NULL,NULL);
  264.         throw(NOT_ACTIVE);
  265.     }
  266.     RC=DoOptions(Port,&Opts,SysBase,DOSBase,RexxSysBase);
  267.     Permit();                                                                            /* We are done */
  268.  
  269.     GetOptions(&Stat,SPC_TAB,RexxSysBase);
  270.     unless(Opts.opt_Quiet)
  271.         EasyRequestArgs(NULL,&InfoReq,NULL,&Stat);
  272.  
  273.     /* Exceptions */
  274.     catch(NOT_ACTIVE,    );
  275.     catch(BAD_ARGS,        );
  276.     catch(NO_REXX,        CloseLibrary((struct Library *)RexxSysBase));
  277.     catch(NO_ICON,        CloseLibrary(IconBase));
  278.     catch(NO_INT,            CloseLibrary((struct Library *)IntuitionBase));
  279.     ReplyMsg((struct Message *)WBMsg);                        /* Reply to Workbench message */
  280.     return(RC);
  281. }    /* WBMode */
  282.  
  283. STATIC LONG DoOptions(struct MsgPort *port, struct Options *opts,
  284.                                             struct ExecBase *SysBase, struct DosLibrary *DOSBase,
  285.                                             struct RxsLib *RexxSysBase)
  286. {
  287.     struct RexxMsg *RXMsg;
  288.     LONG RC=RETURN_OK;                                                        /* Everything looks OK so far */
  289.  
  290.     /* RXC */
  291.     if(opts->opt_RXC)                                                            /* Shut down REXX */
  292.         if(RXMsg=CreateRexxMsg(NULL,NULL,NULL))            /* Create message */
  293.         {
  294.             RXMsg->rm_Action=RXCLOSE | RXFF_NONRET;        /* Set action */
  295.             PutMsg(port,(struct Message *)RXMsg);            /* Send message */
  296.         }
  297.         else                                                                                /* No message */
  298.         {
  299.             SetIoErr(ERROR_NO_FREE_STORE);                        /* Set error code */
  300.             RC=RETURN_ERROR;                                                    /* And mark it */
  301.         }
  302.  
  303.     /* HI */
  304.     if(opts->opt_HI)                                                            /* Interrupt tasks */
  305.     {
  306.         bset(RexxSysBase->rl_Flags,RLFB_HALT);            /* Set interrupt request */
  307.         Signal(port->mp_SigTask,flag(port->mp_SigBit));
  308.     }
  309.  
  310.     /* Suspend/Resume */
  311.     if(opts->opt_Suspend)                                                    /* Suspension requested */
  312.     {
  313.         bset(RexxSysBase->rl_Flags,RLFB_SUSP);            /* Set suspension request */
  314.         Signal(port->mp_SigTask,flag(port->mp_SigBit));
  315.     }
  316.     if(opts->opt_Resume)                                                    /* Resumption requested */
  317.     {
  318.         bclr(RexxSysBase->rl_Flags,RLFB_SUSP);            /* Set reumption request */
  319.         Signal(port->mp_SigTask,flag(port->mp_SigBit));
  320.     }
  321.  
  322.     /* TE/TS */                                                                        /* Tracing enable/disable */
  323.     if(opts->opt_TE)        bclr(RexxSysBase->rl_Flags,RLFB_TRACE);
  324.     if(opts->opt_TS)        bset(RexxSysBase->rl_Flags,RLFB_TRACE);
  325.  
  326.     /* TCO/TCC */
  327.     if(opts->opt_TCO)                                                            /* Open console */
  328.         if(RXMsg=CreateRexxMsg(NULL,NULL,NULL))            /* Create message */
  329.         {
  330.             RXMsg->rm_Action=RXTCOPN | RXFF_NONRET;        /* Set open message */
  331.             PutMsg(port,(struct Message *)RXMsg);            /* Send message */
  332.         }
  333.         else                                                                                /* No message */
  334.         {
  335.             SetIoErr(ERROR_NO_FREE_STORE);                        /* Set error code */
  336.             RC=RETURN_ERROR;                                                    /* Mark error */
  337.         }
  338.     if(opts->opt_TCC)                                                            /* Close console */
  339.         if(RXMsg=CreateRexxMsg(NULL,NULL,NULL))            /* Create message */
  340.         {
  341.             RXMsg->rm_Action=RXTCCLS | RXFF_NONRET;        /* Set open message */
  342.             PutMsg(port,(struct Message *)RXMsg);            /* Send message */
  343.         }
  344.         else                                                                                /* No message */
  345.         {
  346.             SetIoErr(ERROR_NO_FREE_STORE);                        /* Set error code */
  347.             RC=RETURN_ERROR;                                                    /* Mark error */
  348.         }
  349.  
  350.     return(RC);
  351. }    /* DoOptions */
  352.  
  353. STATIC VOID GetOptions(struct States *stat, STRPTR tab, struct RxsLib *rsb)
  354. {
  355.     clear(stat);                                                                    /* Set defaults */
  356.     stat->state_Tab1=stat->state_Tab2=tab;
  357.     stat->state_Tracing=btst(rsb->rl_Flags,RLFB_TRACE) ? MSG_ON : MSG_OFF;
  358.     stat->state_Console=rsb->rl_TraceFH ? MSG_OPEN : MSG_CLOSED;
  359.     if(btst(rsb->rl_Flags,RLFB_SUSP))
  360.     {
  361.         stat->state_Suspended=MSG_IS_SUSPENDED;
  362.         stat->state_Tab3=tab;
  363.     }
  364.     if(btst(rsb->rl_Flags,RLFB_CLOSE))
  365.     {
  366.         stat->state_WillClose=MSG_WILL_CLOSE;
  367.         stat->state_Tab4=tab;
  368.     }
  369. }    /* GetOptions */
  370.